package com.wang.madness.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.wang.madness.config.configBean.JwtConfig;
import com.wang.madness.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;

/**
 * @author 王文君
 */
@Slf4j
@Component
public class JwtUtil {

  private final JwtConfig jwtConfig;

  @Autowired
  public JwtUtil(JwtConfig jwtConfig) {
    this.jwtConfig = jwtConfig;
  }


  /**
   * 生成token
   *
   * @param user 用户对象
   * @return jwt令牌
   */
  public String createToken(User user) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, jwtConfig.getExpiresTimestamp());
    Date date = calendar.getTime();
    return JWT.create().withAudience("" + user.getUserId())
        // 签发对象
        .withIssuedAt(new Date())
        // 发行时间
        .withExpiresAt(date)
        // 有效时间
        .withClaim("userName", user.getUserName())
        .withClaim("loginName", user.getName())
        // 负载
        .sign(Algorithm.HMAC256(user.getUserId() + jwtConfig.getSign()));
    // 加密
  }

  /**
   * 校验token
   *
   * @param token  token
   * @param secret 秘钥
   */
  public boolean verifyToken(String token, String secret) {
    log.info("开始校验token");
    DecodedJWT decodedJWT = null;
    try {
      decodedJWT = JWT.require(Algorithm.HMAC256(secret + "wang")).build().verify(token);
      log.info("token校验通过");
    } catch (Exception e) {
      log.error("非法token=======>" + e.getMessage());
    }
    return decodedJWT != null;
  }

  /**
   * 获取签发对象
   *
   * @param token token
   * @return 签发对象信息
   */
  public String getAudience(String token) {
    String audience = null;
    try {
      audience = JWT.decode(token).getAudience().get(0);
    } catch (JWTDecodeException e) {
      log.error("token解析失败=======>" + e.getMessage());
    }
    return audience;
  }

  /**
   * 通过key获取负载的值
   *
   * @param token token
   * @param name  key
   * @return 负载的值
   */
  public Claim getClaimByName(String token, String name) {
    return JWT.decode(token).getClaim(name);
  }
}
